package com.healthcarex.hip.saas.security.service.impl;

import com.healthcarex.hip.saas.security.config.SecurityProperties;
import com.healthcarex.hip.saas.security.dao.ResourceDao;
import com.healthcarex.hip.saas.security.model.SysResource;
import com.healthcarex.hip.saas.security.service.IPermissionService;
import com.healthcarex.hip.saas.security.util.IPUtils;
import com.healthcarex.hip.saas.security.util.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author ChenPan
 * @date 2018/6/27 10:24
 * description:
 */
@Slf4j
@Service("permissionService")
public class PermissionServiceImpl implements IPermissionService {

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Autowired
    private ResourceDao resourceDao;

    @Autowired
    private SecurityProperties securityProperties;

    @Override
    @Cacheable(value = "urlPermission", key = "'hasPermission_'+#p1.name+'_'+#p0.requestURI+'_'+#p0.method",
            condition = "#p1.name!='anonymousUser'")
    public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
        log.debug("---->  {}", request.getRequestURI());
        Object principal = authentication.getPrincipal();

        if (principal == null) {
            return false;
        }

        if (SecurityUtils.hasRole(securityProperties.roleAdmin)) {
            log.debug("---管理员---");
            return true;
        }
        boolean hasPermission = false;

        if (authentication instanceof AnonymousAuthenticationToken) {
            log.warn("IP:{},URI:{} || 未登录",
                    IPUtils.getIpAddr(request), request.getRequestURI());
            return false;
        }
        List<SimpleGrantedAuthority> grantedAuthorityList = (List<SimpleGrantedAuthority>) authentication
                .getAuthorities();


        if (principal != null) {
            if (CollectionUtils.isEmpty(grantedAuthorityList)) {
                log.warn("角色列表为空：{}", authentication.getPrincipal());
                return false;
            }
            Set<SysResource> resources = new HashSet<>();
            for (SimpleGrantedAuthority authority : grantedAuthorityList) {
                resources.addAll(resourceDao.findResourcesByRole(authority.getAuthority()));
            }
            for (SysResource resource : resources) {
                if (StringUtils.isNotEmpty(resource.getResourceUrl()) && antPathMatcher
                        .match(resource.getResourceUrl(), request.getRequestURI())
                        && request.getMethod().equalsIgnoreCase(resource.getRequestType())) {
                    hasPermission = true;
                    break;
                }
            }
        }
        return hasPermission;
    }
}
